package com.example.werewolf.todo;

import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import org.springframework.ai.chat.client.ChatClient;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class AIPlayerAgent {

    // ========== 核心身份与状态 ==========

    /**
     * 玩家的唯一标识符 (1-8)
     */
    private final String playerId;

    /**
     * 玩家的真实身份 (狼人, 预言家, 女巫, 猎人, 平民)
     */
    private final String role;

    /**
     * 玩家当前是否存活
     */
    private boolean isAlive = true;

    /**
     * 玩家是否是警长
     */
    private boolean isSheriff = false;

    // ========== AI 交互核心 ==========

    /**
     * Spring AI 的聊天客户端，用于与 LLM 进行对话
     */
    private final ChatClient chatClient;

    /**
     * 系统提示词 (System Prompt)
     * 包含角色、目标、行为准则
     */
    private String systemPrompt;

    /**
     * 游戏专属的上下文记忆 (可选，用于更复杂的AI)
     * 一个简单的键值对，用于存储AI在游戏过程中“记住”的关键信息。
     * 例如：
     *   - "seerCheckedPlayer5": "wolf" (预言家查验结果)
     *   - "suspectedWolves": "[2, 7]" (AI自己怀疑的狼人列表)
     *   - "alliance": "[3]" (狼人队友编号)
     */
    private Map<String, Object> personalMemory;

    // ========== 游戏进程追踪 ==========

    /**
     * 该玩家在本局游戏中所有的发言历史
     * 用于在后续发言中保持一致性，或供“复盘”分析。
     */
    private List<String> speechHistory;

    /**
     * 该玩家在本局游戏中所有的行动历史 (投票、刀人、用药等)
     * 用于追踪其行为模式。
     */
    private List<GameAction> actionHistory;

    /**
     * 该玩家收到的“私有信息”列表
     * 例如：预言家收到的查验结果，女巫收到的死亡信息和用药反馈。
     * 这些信息会被整合进 systemPrompt 或 personalMemory。
     */
    private List<PrivateMessage> privateMessages;

    // ========== 构造函数 ==========

    public AIPlayerAgent(String playerId, String role, ChatClient chatClient) {
        this.playerId = playerId;
        this.role = role;
        this.chatClient = chatClient;
        this.personalMemory = new HashMap<>();
        this.speechHistory = new ArrayList<>();
        this.actionHistory = new ArrayList<>();
        this.privateMessages = new ArrayList<>();
        this.initializeSystemPrompt(); // 初始化系统提示词
    }

    // ========== 核心方法 ==========

    /**
     * 执行动作
     * @param gameState 当前全局游戏状态
     * @param userPrompt 当前阶段的具体指令 (User Prompt)
     * @return 结构化的游戏动作
     */
    public GameAction act(GameState gameState, String userPrompt) {
        // 1. 构建完整的 Prompt (System + User)
        String fullPrompt = buildFullPrompt(gameState, userPrompt);

        // 2. 调用 LLM
        String llmResponse = chatClient.prompt()
                .system(systemPrompt)
                .user(fullPrompt)
                .call()
                .content();

        // 3. 解析 LLM 的响应为 GameAction 对象
        GameAction action = parseLlmResponseToAction(llmResponse);

        // 4. 记录行动/发言到历史
        if ("发言".equals(action.getActionType())) {
            speechHistory.add(action.getContent());
        } else {
            actionHistory.add(action);
        }

        return action;
    }

    /**
     * 接收一条私有信息 (由 GameEngine 调用)
     * @param message 私有信息内容
     */
    public void receivePrivateMessage(PrivateMessage message) {
        this.privateMessages.add(message);
        // 可选：立即更新 systemPrompt 或 personalMemory
        // updateSystemPromptWithNewInfo(message);
    }

    // ========== 私有辅助方法 ==========

    /**
     * 初始化系统提示词
     */
    private void initializeSystemPrompt() {
        this.systemPrompt = String.format(
                "你是一个参与“8人标准狼人杀”游戏的AI玩家，你的身份是：%s。\n" +
                        "你的玩家编号是：%s。\n" +
                        "你的核心目标：...\n" + // 此处省略完整目标描述
                        "你的行为准则：...\n" + // 此处省略完整行为准则
                        "请根据当前阶段的任务，给出你的 [发言/行动/投票]。你的回复必须严格遵循以下JSON格式：...",
                this.role, this.playerId
        );
    }

    /**
     * 构建完整的 Prompt，包含当前游戏状态摘要
     */
    private String buildFullPrompt(GameState gameState, String userPrompt) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("【当前游戏状态摘要】\n");
        prompt.append("存活玩家: ").append(gameState.getAlivePlayers()).append("\n");
        prompt.append("当前阶段: ").append(gameState.getCurrentPhase()).append("\n");
        prompt.append("历史关键事件: \n").append(gameState.getHistorySummary()).append("\n\n");
        prompt.append("【你的个人记忆】\n"); // 可选，将 personalMemory 转为字符串
        prompt.append("... \n\n");
        prompt.append(userPrompt); // 追加当前阶段的具体指令
        return prompt.toString();
    }

    /**
     * 将 LLM 的文本响应解析为 GameAction 对象
     * 这里需要健壮的错误处理和重试逻辑
     */
    private GameAction parseLlmResponseToAction(String llmResponse) {
        try {
            // 假设使用 Jackson 进行 JSON 反序列化
            return JSONObject.parseObject(llmResponse, GameAction.class);
        } catch (Exception e) {
            // 解析失败，可以尝试修复、重试或抛出异常
            throw new RuntimeException("Failed to parse LLM response: " + llmResponse, e);
        }
    }
}